package ms.unicorn.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;

public class ReflectionUtil {
	
	public static List<Bundle> bundles = new ArrayList<Bundle>();
	
	public static void registerBundle(String pluginID) {
		Bundle bundle = Platform.getBundle(pluginID);
		if (bundle != null && bundles.indexOf(bundle) < 0)
			bundles.add(bundle);
			
	}
	
	public static Class<?> getClass(String className) {
		Class<?> clazz = null;
		try {			 
			clazz = Class.forName(className);
		} catch (Exception e) {
			if (className != null && className.length() > 0)
				for(Bundle bundle: bundles)
					try {
						clazz = bundle.loadClass(className);
						return clazz;
					}
					catch(Exception e1) {}
		}
		return clazz;
	}
	
	public static Class<?> getClass(String className, ClassLoader loader) {
		Class<?> clazz = null;
		try {
			clazz = Class.forName(className, true, loader);
		} catch (Exception e) {
			//e.printStackTrace();
		}
		return clazz;
	}
	
	public static Class<?> getClass(String className, Class<?> defaultClass) {
		Class<?> clazz = getClass(className);
		return clazz != null ? clazz : defaultClass;
	}
	
	public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) {
		Method med;
		try {
			med = clazz.getMethod(methodName, params);
		} catch (Exception e) {
			med = null;
		}
		return med;
	}
	
	public static Object invoke(Method method, Object target, Object...params) {
		try {
			return method.invoke(target, params);
		} catch (Exception e) {
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T getPropertyValue(Object target, String propertyName, T defaultValue) {
		try {
			String medName = "get" + propertyName;
			Method m = target.getClass().getMethod(medName);
			return (T)m.invoke(target);
		} catch (Exception e) {
			return defaultValue;
		}
	}
	
	public static void setPropertyValue(Object target, String propertyName, Object value) {
		int idx = propertyName.indexOf('.');
		if (idx > 0) {
			Object newTarget = getPropertyValue(target, propertyName.substring(0, idx), null);
			String newPropertyName = propertyName.substring(idx + 1);
			setPropertyValue(newTarget, newPropertyName, value);
		}
		else 
			try {
				String medName = "set" + propertyName;
				for(Method m: target.getClass().getMethods())
					if (m.getName().equalsIgnoreCase(medName)) {
						m.invoke(target, value);
						return;
					}
			} catch (Exception e) {}
	}
	
}
